﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace PFAGame
{
    public class Specialiste : APlayer
    {
        const float lifeByLvl = 10;
        const float attackSpeedByLvl = 0.93f;
        const float moveSpeedByLvl = 0.2f;
        const float damageByLvl = 1.1f;
        const float resistByLvl = 0.3f;
        const float projectileSpeedByLvl = 0.6f;
        const float critikByLvl = 5;

        bool canAttack = true;
        float timeSinceLastAttack;

        float projectileSpeed = 15.0f;

        static SoundEffect sound;
        SoundEffectInstance soundInstance;

        public class ShootData
        {
            public float Dammage
            {
                get;
                private set;
            }
            public float Speed
            {
                get;
                private set;
            }
            public Vector2 Orientation
            {
                get;
                private set;
            }
            public Vector2 Position
            {
                get;
                private set;
            }

            public ShootData()
            {
            }

            public ShootData(float dammage, float speed, Vector2 orientation, Vector2 position)
            {
                this.Dammage = dammage;
                this.Speed = speed;
                this.Orientation = orientation;
                this.Position = position;
            }

            public void Serialize(Microsoft.Xna.Framework.Net.PacketWriter packetWriter)
            {
                if (packetWriter == null)
                    throw new ArgumentNullException("packetWriter");

                packetWriter.Write(this.Dammage);
                packetWriter.Write(this.Speed);
                packetWriter.Write(this.Orientation);
                packetWriter.Write(this.Position);
            }

            public void Deserialize(Microsoft.Xna.Framework.Net.PacketReader packetReader)
            {
                if (packetReader == null)
                    throw new ArgumentNullException("packetReader");

                this.Dammage = packetReader.ReadSingle();
                this.Speed = packetReader.ReadSingle();
                this.Orientation = packetReader.ReadVector2();
                this.Position = packetReader.ReadVector2();
            }
        }

        public delegate void ShootEventHandler(object sender, ShootData shootData);
        public static event ShootEventHandler shootEvent;

        public float ProjectileSpeed
        {
            get { return projectileSpeed; }
            set { projectileSpeed = value; }
        }

        public override void init()
        {
            base.init();
            playerCLass = e_class.SPECIALISTE;

            moveRightAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunLeft"), 503, 504, 2, (int)(100 / moveSpeed), true);
            moveLeftAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunRight"), 503, 504, 2, (int)(100 / moveSpeed), true);
            moveUpAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunUp"), 503, 504, 2, (int)(100 / moveSpeed), true);
            moveDownAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunDown"), 503, 504, 2, (int)(100 / moveSpeed), true);

            attackRightAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunLeft"), 503, 504, 2, (int)(30 * attackSpeed), false);
            attackLeftAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunRight"), 503, 504, 2, (int)(30 * attackSpeed), false);
            attackUpAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunUp"), 503, 504, 2, (int)(30 * attackSpeed), false);
            attackDownAnim.Initialize(ScreenManager.Singleton.Game.Content.Load<Texture2D>("Images/Mob/Alice/AliceRunDown"), 503, 504, 2, (int)(30 * attackSpeed), false);

            if (sound == null)
                sound = ScreenManager.Singleton.Game.Content.Load<SoundEffect>("Sound_effects/gun_shot");
            soundInstance = sound.CreateInstance();
            soundInstance.Volume = 0.2f;
            soundInstance.IsLooped = false;
        }

        public override void HandleInput(GameTime gameTime, InputState input)
        {
            // la gestion des déplacements est effectué dans APlayer
            base.HandleInput(gameTime, input);

            PlayerIndex tmpPlayerIndex;

            // attaque
            isAttacking = !canAttack;

            timeSinceLastAttack += ((float)gameTime.ElapsedGameTime.Ticks / 10000000);
            if (timeSinceLastAttack >= attackSpeed / attackSpeedBuffMultiplicator)
                canAttack = true;
            if (canAttack && fire1.Evaluate(input, playerIndex, out tmpPlayerIndex))
            {
                canAttack = false;
                timeSinceLastAttack = 0;

                attackLeftAnim.reset();
                attackDownAnim.reset();
                attackRightAnim.reset();
                attackUpAnim.reset();

                // instancie un nouveau projectile
                ProjectileSpecialist projectile = new ProjectileSpecialist();
                projectile.Position = position;
                projectile.Orientation = -orientation; // (-): ??
                if (random.Next(100) <= criticalChance)
                {
                    projectile.Dammage = dammage * criticalMultiplicator * dammageBuffMultiplicator;
                    projectile.color = Color.Purple;
                    projectile.PiercingCount = 100;
                }
                else
                {
                    projectile.Dammage = dammage * dammageBuffMultiplicator;
                    projectile.color = Color.Red;
                }
                projectile.init();
                projectile.Speed = projectileSpeed;
                soundInstance.Play();

                if (GameplayScreen.Singleton.NetworkSessionP == null || GameplayScreen.Singleton.NetworkSessionP.IsHost == true)
                    GameplayScreen.Singleton.ProjectileList.Add(projectile);
                else
                    shootEvent(this, new ShootData(projectile.Dammage, projectile.Speed, projectile.Orientation, projectile.Position));
            }
        }

        public override bool upHealth(bool init)
        {
            if (!init && !base.upHealth(false))
                return false;

            maxLife += lifeByLvl;
            life += lifeByLvl;

            return true;
        }

        public override bool upDamage(bool init)
        {
            if (!init && !base.upDamage(false))
                return false;

            dammage += damageByLvl;
            criticalChance += critikByLvl;
 
            return true;
        }

        public override bool upAttackSpeed(bool init)
        {
            if (!init && !base.upAttackSpeed(false))
                return false;

            attackSpeed *= attackSpeedByLvl;
            projectileSpeed += projectileSpeedByLvl;

            return true;
        }

        public override bool upMoveSpeed(bool init)
        {
            if (!init && !base.upMoveSpeed(false))
                return false;

            moveSpeed += moveSpeedByLvl;

            return true;
        }

        public override bool upResist(bool init)
        {
            if (!init && !base.upResist(false))
                return false;

            resist += resistByLvl;

            return true;
        }

        internal override string getClass()
        {
            return "Spécialiste";
        }
    }
}
